/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_Studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/


#include "物理引擎测试.h"

#include "面/几何模型生成.h"

#include "../A_引擎/引擎.h"
#include <文件/file_载入保存数据.h>


#include "物理/物理.h"
#include "物体/物体.h"







void f_test_NewTon() {
	S_物理解算器 解算器;

	vec3 size1 = { 100.0f, 0.1f, 100.0f };
	vec3 size2 = { 1.0f, 1.1f, 1.0f };

	auto* 材质 = f_创建材质(&解算器, 0.5, 0.5, 0.5);
	auto* box1 = f_创建方体几何体(&解算器, size1, E_物理引擎::E_物理引擎_Bullet);
	auto* box2 = f_创建方体几何体(&解算器, size2, E_物理引擎::E_物理引擎_Bullet);
	auto* plane = f_创建平面几何体(&解算器, { 0.0f,1.0f,0.0f,0.0f }, E_物理引擎::E_物理引擎_Bullet);

	S_Tranform t;
	
	auto* body1 = f_创建静态碰撞(&解算器, *box1, *材质, t);
	auto* body2 = f_创建刚体(&解算器, *box2, *材质, t);
	auto* body3 = f_创建静态碰撞(&解算器, *plane, *材质, t);

	f_物理体添加到引擎(&解算器, body1, 0, E_物理引擎::E_物理引擎_Bullet);
	f_物理体添加到引擎(&解算器, body2, 0, E_物理引擎::E_物理引擎_Bullet);
	f_物理体添加到引擎(&解算器, body3, 0, E_物理引擎::E_物理引擎_Bullet);

	解算器.f_set帧率(1.0 / 2060.0);


	body3->f_setLocRot({ 0.0f, 3.0f, 0.0f }, { 0.0f,0.0f,0.0 });
	body1->f_setLocRot({ 0.0f, -5.0f, 0.0f }, { 0.0f,0.0f,0.0 });
	body2->f_setLocRot({ 0.0f, 10.0f, 0.0f }, { 0.0f,0.0f,0.0 });

	for (uint32 i = 0; i < 1000000; ++i) {
		解算器.f_模拟();

		std::vector<Mat44f> mat;
		std::vector<void*> userData;
		解算器.f_取更新物体(mat, userData);

		//if (mat.size() > 1 ) {
		//	std::cout << mat[1].m31 << std::endl;
		//}
	}
	



	//auto* 材质 = f_创建材质(&解算器, 0.5, 0.5, 0.5);
}

void f_test_Bullet() {
	E_物理引擎 物理引擎 = E_物理引擎::E_物理引擎_Bullet;
	//E_物理引擎 物理引擎 = E_物理引擎::E_物理引擎_PhysX;

	






	auto* 材质 = f_创建材质(&S_框架::g_Scene->m_Physics, 0.5, 0.5, 0.5, 物理引擎);

	vec3 boxSize = { 1.5, 0.5, 2.5 };
	vec3 boxSize2 = { 100.5, 0.15, 200.5 };
	auto* box1 = f_创建方体几何体(&S_框架::g_Scene->m_Physics, boxSize/2, 物理引擎);
	auto* box2 = f_创建方体几何体(&S_框架::g_Scene->m_Physics, boxSize2, 物理引擎);
	auto* plane = f_创建平面几何体(&S_框架::g_Scene->m_Physics, { 0.0f,1.0f,0.0f,-2.0f }, 物理引擎);


	S_Tranform t;
	auto* body1 = f_创建静态碰撞(&S_框架::g_Scene->m_Physics, *box2, *材质, t);
	auto* body2 = f_创建刚体(&S_框架::g_Scene->m_Physics, *box1, *材质, t);
	auto* 平面 = f_创建静态碰撞(&S_框架::g_Scene->m_Physics, *plane, *材质, t);
	
	//f_物理体添加到引擎(&S_Core::g_Scene->m_Physics, body2, 0, 物理引擎);
	f_物理体添加到引擎(&S_框架::g_Scene->m_Physics, 平面, 0, 物理引擎);


	body2->f_setLocRot({ 0.0f, 5.0f, 0.0f }, { 0.0f,0.0f,0.0 });
	平面->f_setLocRot({ 0.0f, -1.0f, 0.0f }, { 0.0f,0.0f,0.0 });



	auto* 物体box = f_创建BOX物体(boxSize, S_框架::ctx);
	f_ob_set材质(物体box, S_框架::g_索引绘制材质);
	S_框架::g_Scene->m_物体.push_back(物体box);
	body2->f_绑定关联对象(物体box);






	S_框架::g_Scene->m_Physics.m_Bullet->m_步进时间 = 1.0 / 60.0;
	S_框架::g_Scene->m_Physics.m_PhysX->m_步进时间 = 1.0 / 60.0;




	uint32 车辆数量 = 10;


	auto* 物体carBox = f_创建BOX物体(boxSize, S_框架::ctx);
	f_ob_set材质(物体carBox, S_框架::g_索引绘制材质);
	S_框架::g_Scene->m_物体.push_back(物体carBox);

	std::vector<S_物体*> 车体s = 物体carBox->f_创建实例(车辆数量);


	//std::vector<S_物体*> 车轮s(车辆数量*4);
	auto* 车轮 = f_创建圆柱物体({ 0.2, 0.25, 0.25 }, 32, S_框架::ctx);
	f_ob_set材质(车轮, S_框架::g_索引绘制材质);
	S_框架::g_Scene->m_物体.push_back(车轮);

	

	
	std::vector<vec3> 车轮网格顶点(32 * 2);

	f_构建圆柱_v3(0.2, 0.25, 32, 车轮网格顶点.data());
	S_三角Mesh 轮胎mesh;
	轮胎mesh.m_vert = 车轮网格顶点.data();
	轮胎mesh.m_vNum = 车轮网格顶点.size();
	auto gem = f_创建凸壳物理包围几何(&S_框架::g_Scene->m_Physics, 轮胎mesh, 物理引擎);


	auto* box = f_创建方体几何体(&S_框架::g_Scene->m_Physics, boxSize / 2, 物理引擎);
	box->f_set质量(2);
	for (uint32 i = 0; i < 车辆数量; ++i) {
		//auto* 材质 = f_创建材质(&S_Core::g_Scene->m_Physics, 0.8, 0.5, 0.5, E_物理引擎::E_物理引擎_Bullet);
		auto* carBox = f_创建刚体(&S_框架::g_Scene->m_Physics, *box, *材质, t);
		carBox->m_ID = i;

		std::vector<S_车轮参数> 车轮属性(4);
		//std::vector<S_物理体*> 车轮(4);
		for (uint8 i车轮s = 0; i车轮s < 4; ++i车轮s) {
			车轮属性[i车轮s].m_精度 = 32;
			车轮属性[i车轮s].m_安放方位 = E_车轮ID(i车轮s);
			车轮属性[i车轮s].m_半径 = 0.25;
			车轮属性[i车轮s].m_手刹强度 = 100;
			车轮属性[i车轮s].m_重量 = 30.0;
			车轮属性[i车轮s].m_轮胎宽度 = 0.2;
			车轮属性[i车轮s].m_悬挂压缩方向 = { 0.0f, -1.0f, 0.0f };
			车轮属性[i车轮s].m_悬挂刚度 = 10.9;
			车轮属性[i车轮s].m_悬挂阻尼 = 200.0;
			车轮属性[i车轮s].m_悬挂压缩 = 4.0;
			//车轮属性[i车轮s].m_悬挂压缩 = 0.5;

			车轮属性[i车轮s].m_轮胎摩擦 = 1.0;
			车轮属性[i车轮s].m_旋转影响 = 0.05;

			车轮属性[i车轮s].m_车轮物理体 = f_创建物理车轮(&S_框架::g_Scene->m_Physics, *gem, *材质, 车轮属性[i车轮s]);

		}
		车轮属性[0].m_位置 = { -0.8f, -0.2f, 1.0f };
		车轮属性[1].m_位置 = { 0.8f, -0.2f, 1.0f };
		车轮属性[2].m_位置 = { -0.8f, -0.2f, -1.0f };
		车轮属性[3].m_位置 = { 0.8f, -0.2f, -1.0f };


		std::vector<S_物理几何体*> 车体geom(1);
		std::vector<S_物理材质*> materials(1);
		车体geom[0] = box;
		materials[0] = 材质;


		S_车体参数 车体参数;
		车体参数.m_车体刚体 = carBox;
		车体参数.m_底盘重量 = 1500;
		车体参数.m_引擎_最大扭矩 = 800;
		车体参数.m_引擎_最大转速 = 8000;
		车体参数.m_变速_换挡时间 = 0.2;
		车体参数.m_车体材质 = &材质;

		//车体参数.m_车体物理体 = 车体geom.data();
		车体参数.m_车体材质 = materials.data();
		//车体参数.m_车体部件数量 = 1;
		车体参数.m_车轮 = 车轮属性.data();
		车体参数.m_车轮数量 = 4;



		auto* 车 = f_创建物理车辆(&S_框架::g_Scene->m_Physics, 车体参数);
		f_物理体添加到引擎(&S_框架::g_Scene->m_Physics, 车, 0);



		
		carBox->f_setLocRot({ 3.0f*i-50.0f, 2.0f, 0.0f }, { 0.0f,0.0f,0.0 });
		车->f_绑定关联对象(车体s[i]);
		车->m_ID = i;
		车体s[i]->m_ID = i;


		std::vector<S_物体*> 车轮s = 车轮->f_创建实例(4);
		for (uint32 k = 0; k < 4; ++k) {
			车->f_绑定关联对象(车轮s[k], k);
		}
	}




	//return;

	/*std::vector<vec3> p;
	f_随机向量(p, 10, { -60.0, 60.0 }, 10, { 1.0f, 0.0f, 1.0f });
	uint32 v = 0;
	auto 静态碰撞体 = 物体box->f_创建实例(10);
	for (auto& obj: 静态碰撞体) {
		auto* PhyBox = f_创建刚体(&S_Core::g_Scene->m_Physics, *box1, *材质, t);
		PhyBox->f_绑定关联对象(obj);
		
		PhyBox->f_setLoc(p[v]);
		++v;

		f_物理体添加到引擎(&S_Core::g_Scene->m_Physics, PhyBox, 0);
	}*/


	return;
	
	std::vector<S_物体*> objs;
	f_读文件("I:/Item/02.ms", [&](FILE* f) {
		objs = f_load多物体(f, S_框架::ctx);
	});
	
	

	
	for (auto& obj : objs) {
		if (obj->m_Type == E_物体类型::t_网格) {
			S_物理几何体* 插件碰撞体gem = 0;
			f_from模型三角网格(obj, [&](S_三角Mesh& mesh) {
				插件碰撞体gem = f_创建网格物理几何体(&S_框架::g_Scene->m_Physics, mesh, 物理引擎);
				});
			auto* 地形碰撞 = f_创建静态碰撞(&S_框架::g_Scene->m_Physics, *插件碰撞体gem, *材质, t);
			f_物理体添加到引擎(&S_框架::g_Scene->m_Physics, 地形碰撞, 0);

			f_ob_set材质(obj, S_框架::g_索引绘制材质);
			obj->m_Name = L"场景";
			S_框架::g_Scene->m_物体.push_back(obj);
			break;
		}
	}
	

}





